//
//  IMMessageManager.m
//  IMChezhil
//
//  Created by zhangliucheng on 15/7/26.
//  Copyright (c) 2015年 CheZhil. All rights reserved.
//

#import "IMMessageManager.h"
#import "IMTextMessage.h"
#import "IMImageMessage.h"
#import "IMAudioMessage.h"
#import "IMCore.h"
#import "FMDatabase.h"

#define DATABASE            @"chezhil_im.db"
#define CREATE_SQL          @"create table if not exists message (userId text, messageId text, messageType integer, messageDirction integer,\
sendStatus integer, readStatus integer, messageContent text, imageFileUrl text, imageFilePath text,\
audioFileUrl text, audioFilePath text, createTime long)"
#define RECENT_MESSAGE      @"select * from message where userId=? order by createTime DESC limit ?"
#define UNREAD_MESSAGE      @"select count(*) from message where userId=? and readStatus=0"
#define MESSAGE_BY_ID       @"select * from message where userId=? and messageId=?"
#define SAVE_MESSAGE        @"insert into message values (:userId, :messageId, :messageType, :messageDirction, :sendStatus, :readStatus, :messageContent, :imageFileUrl, :imageFilePath, :audioFileUrl, :audioFilePath, :createTime)"
#define UPDATE_MESSAFE      @"update message set sendStatus=:sendStatus, readStatus=:readStatus"
#define UPDATE_SEND_STATUS  @"update message set sendStatus=1 where userId=?"
#define UPDATE_READ_STATUS  @"update message set readStatus=1 where userId=?"


@interface IMMessageManager ()

@property (nonatomic, strong) FMDatabase *db;

@end

@implementation IMMessageManager

+ (instancetype)shareInstance {
    static IMMessageManager *_sharedManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedManager = [IMMessageManager new];
    });
    return _sharedManager;
}

- (instancetype)init {
    self = [super init];
    if (self) {
        self.db = [self getFMDBDatabase];
        [self createTable];
    }
    return self;
}

- (FMDatabase *)getFMDBDatabase {
    NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *path = [documentPath stringByAppendingPathComponent:DATABASE];
    FMDatabase *database = [FMDatabase databaseWithPath:path];
    if ([database open]) {
        return database;
    }
    return NULL;
}

- (void)createTable {
    if ([self.db open]) {
        [self.db executeUpdate:CREATE_SQL];
        [self.db close];
    }
}

- (NSMutableArray *)getRecentMessages:(NSInteger)count {
    [self updateReadStatus];
    NSMutableArray *messages = [NSMutableArray new];
    if ([self.db open]) {
        FMResultSet * result = [self.db executeQuery:RECENT_MESSAGE, [[IMCore shareInstance] getUin], [NSString stringWithFormat:@"%d", count]];
        while ([result next]) {
            IMUserMessage *msg = [self getMessageFromResult:result];
            [messages insertObject:msg atIndex:0];
        }
        [result close];
        [self.db close];
    }
    return messages;
}

- (NSInteger)getUnReadCount {
    NSInteger count = 0;
    if ([self.db open]) {
        FMResultSet * result = [self.db executeQuery:UNREAD_MESSAGE, [[IMCore shareInstance] getUin]];
        if ([result next]) {
            count = [result intForColumnIndex:0];
        }
        [self.db close];
    }
    return count;
}

- (IMUserMessage *)getMessageById:(NSString *)messageId {
    IMUserMessage *message;
    if ([self.db open]) {
        
        FMResultSet * result = [self.db executeQuery:MESSAGE_BY_ID, [[IMCore shareInstance] getUin]];
        if ([result next]) {
            message = [self getMessageFromResult:result];
        }
        [result close];
        [self.db close];
    }
    return message;
}

- (void)saveMessage:(IMUserMessage *)message {
    NSMutableDictionary *dict = [NSMutableDictionary new];
    [dict setObject:message.userId forKey:@"userId"];
    [dict setObject:message.messageId forKey:@"messageId"];
    [dict setObject:[NSNumber numberWithInteger:message.messageType] forKey:@"messageType"];
    [dict setObject:[NSNumber numberWithInteger:message.messageDirection] forKey:@"messageDirction"];
    [dict setObject:[NSNumber numberWithInteger:message.sentStatus] forKey:@"sendStatus"];
    [dict setObject:[NSNumber numberWithInteger:message.readStatus] forKey:@"readStatus"];
    [dict setObject:[NSNumber numberWithLongLong:message.createdTime] forKey:@"createTime"];
    [dict setObject:[message valueForKey:@"content"] forKey:@"messageContent"];
    [dict setObject:[message valueForKey:@"imageFilePath"] forKey:@"imageFilePath"];
    [dict setObject:[message valueForKey:@"imageFileUrl"] forKey:@"imageFileUrl"];
    [dict setObject:[message valueForKey:@"audioFilePath"] forKey:@"audioFilePath"];
    [dict setObject:[message valueForKey:@"audioFileUrl"] forKey:@"audioFileUrl"];
    
    if ([self.db open]) {
        [self.db executeUpdate:SAVE_MESSAGE withParameterDictionary:dict];
        [self.db close];
    }
}

- (void)saveMessages:(NSArray *)messages {
    if ([self.db open]) {
        [self.db beginTransaction];
        @try {
            for (IMUserMessage *msg in messages) {
                [self saveMessage:msg];
            }
            [self.db commit];
        }
        @catch (NSException *exception) {
            [self.db rollback];
        }
        [self.db close];
    }
}

- (void)updateMessage:(IMUserMessage *)message {
    NSMutableDictionary *dict = [NSMutableDictionary new];
    [dict setObject:[NSNumber numberWithInteger:message.sentStatus] forKey:@"sendStatus"];
    [dict setObject:[NSNumber numberWithInteger:message.readStatus] forKey:@"readStatus"];
    if ([self.db open]) {
        [self.db executeUpdate:UPDATE_MESSAFE withParameterDictionary:dict];
        [self.db close];
    }
}

- (void)updateSendStatus {
    if ([self.db open]) {
        [self.db executeUpdate:UPDATE_SEND_STATUS, [[IMCore shareInstance] getUin]];
        [self.db close];
    }
}

- (void)updateReadStatus {
    if ([self.db open]) {
        [self.db executeUpdate:UPDATE_READ_STATUS, [[IMCore shareInstance] getUin]];
        [self.db close];
    }
}

- (IMUserMessage *)getMessageFromResult:(FMResultSet *)result {
    NSInteger type = [result intForColumn:@"messageType"];
    IMUserMessage *message;
    
    if (type == MessageTypeText) {
        message = [IMTextMessage new];
    } else if (type == MessageTypeImage) {
        message = [IMImageMessage new];
    } else {
        message = [IMAudioMessage new];
    }
    message.userId = [result stringForColumn:@"userId"];
    message.messageId = [result stringForColumn:@"messageId"];
    message.createdTime = [result longLongIntForColumn:@"createTime"];
    message.messageType = [result intForColumn:@"messageType"];
    message.messageDirection = [result intForColumn:@"messageDirction"];
    message.sentStatus = [result intForColumn:@"sendStatus"];
    message.readStatus = [result intForColumn:@"readStatus"];
    
    [message setValue:[result stringForColumn:@"messageContent"] forKey:@"content"];
    [message setValue:[result stringForColumn:@"imageFilePath"] forKey:@"imageFilePath"];
    [message setValue:[result stringForColumn:@"imageFileUrl"] forKey:@"imageFileUrl"];
    [message setValue:[result stringForColumn:@"audioFilePath"] forKey:@"audioFilePath"];
    [message setValue:[result stringForColumn:@"audioFileUrl"] forKey:@"audioFileUrl"];
    
    return message;
}
@end
